{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## **演示0104：数组元素查找与统计**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **案例1：数组极值**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **一维数组极值**\n",
    ">* *np.max*和*np.min*用于查找最大值和最小值\n",
    ">* *np.argmax*和*np.argmax*用于查找极值元素对应的下标索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "最大元素下标： 6 最大值： 8\n",
      "最小元素下标： 1 最小值： 1\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "a = np.array([3, 1, 7, 4, 2, 5, 8])\n",
    "print(\"最大元素下标：\", np.argmax(a), \"最大值：\", np.max(a))\n",
    "print(\"最小元素下标：\", np.argmin(a), \"最小值：\", np.min(a))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **二维数组极值**  \n",
    ">* 设置*axis=0*，表示沿着竖直方向(行索引增长的方向)，为每一列分别查找极值(一维数组，长度为原二维数组列数)\n",
    ">* 设置*axis=1*，表示沿着水平方向(列索引增长的方向)，为每一行分别查找极值(一维数组，长度为原二维数组行数)\n",
    ">* 不设置*axis*时，将查找整个数组中的极值元素(单个值，标量)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "6\n",
      "[4 5 6]\n",
      "[3 6]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([[1,2,3],[4,5,6]])\n",
    "b = np.max(a)\n",
    "c = np.max(a, axis=0)\n",
    "d = np.max(a, axis=1)\n",
    "print(b)\n",
    "print(c)\n",
    "print(d)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **二维数组极值对应的元素索引**\n",
    ">* *argmax*和*argmin*返回极值对应的索引\n",
    ">* 如果没有指定*axis*，则返回极值元素在整个二维数组中的索引号(将二维数组展成一维数组)\n",
    ">* *axis=0*时，分别返回每个列的极值在该列中的索引号\n",
    ">* *axis=1*时，分别返回每个行的极值在该行中的索引号"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n",
      "[1 1 1]\n",
      "[2 2]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([[1,2,3],[4,5,6]])\n",
    "b = np.argmax(a)\n",
    "c = np.argmax(a, axis=0)\n",
    "d = np.argmax(a, axis=1)\n",
    "print(b)\n",
    "print(c)\n",
    "print(d)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **案例2：求和、平均值**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **算数平均值与加权平均值**  \n",
    ">* *np.mean*用于计算算数平均值\n",
    ">* *np.average*计算加权平均值。需要给定一个权重数组(数组中每个权重对应着待统计数组中的每个元素值)\n",
    ">* 可以这样理解加权计算：将权重数组中的每个元素值换算成占总权重数的百分比，然后与待统计数组中对应的元素做乘积，最后求和"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5.5\n",
      "5.5\n",
      "5.0\n"
     ]
    }
   ],
   "source": [
    "a = np.arange(1, 11)\n",
    "print(np.mean(a))\n",
    "weights1 = np.ones(10)\n",
    "print(np.average(a, weights=weights1))    # 权重数组中每个竖直都为1，可视为每个权重都是0.1\n",
    "weights2 = [1,0,1,0,1,0,1,0,1,0]    # 权重换算成百分比后为：[0.2，0，0.2，0，0.2，0，0.2，0，0.2，0]\n",
    "print(np.average(a, weights=weights2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5.500000000000001\n",
      "5.0\n"
     ]
    }
   ],
   "source": [
    "# 自定义的加权平均计算方法\n",
    "def my_average(arr, weights):\n",
    "    weights = weights / np.sum(weights)\n",
    "    average = 0.0\n",
    "    for i in range(len(arr)):\n",
    "        average += arr[i] * weights[i]\n",
    "    return average\n",
    "\n",
    "print(my_average(a, weights1))\n",
    "print(my_average(a, weights2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **二维数组的和与均值计算**  \n",
    ">* 不设置*axis*时，计算整个二维数组的和/均值\n",
    ">* *axis=0*时，沿竖直方向(行索引增长的方向)，计算每个列的和/均值\n",
    ">* *axis=1*时，沿水平方向(列索引增长的方向)，计算每个行的和/均值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "21 3.5\n",
      "[5 7 9] [2.5 3.5 4.5]\n",
      "[ 6 15] [2. 5.]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([[1,2,3],[4,5,6]])\n",
    "print(np.sum(a), np.mean(a))\n",
    "print(np.sum(a, axis=0), np.mean(a, axis=0))\n",
    "print(np.sum(a, axis=1), np.mean(a, axis=1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **案例3：统计非零元素个数**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **统计一维和二维数组中的非零元素个数**\n",
    ">* *np.count_nonzero*\n",
    ">* 通过设置*axis*参数，可以计算每列或每行的非零元素个数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "6\n",
      "[2 1 1 2]\n",
      "[2 2 2]\n"
     ]
    }
   ],
   "source": [
    "a= np.array([[1,2,0,0],[1,0,0,1],[0,0,1,1]])\n",
    "print(np.count_nonzero(a))\n",
    "print(np.count_nonzero(a,axis=0))\n",
    "print(np.count_nonzero(a,axis=1))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
